<template>
  <div class="file-upper">
    <el-upload
      ref="upload"
      drag
      action
      :on-change="handleChange"
      :multiple="multiple"
      :file-list="fileList"
      :auto-upload="false"
    >
      <i class="el-icon-upload"></i>
      <div class="el-upload__text">
        将文件拖到此处，或
        <em>点击上传</em>
      </div>
    </el-upload>
    <div class="content">
      <el-table
        v-if="fileList.length"
        :data="fileList"
        size="small"
        :show-header="false"
        style="width: 100%"
      >
        <el-table-column
          align="left"
          prop="name"
          min-width="200"
        >
          <template slot-scope="{ row }">
            <image-type
              :width="20"
              :fileType="row.fileType"
            >{{row.name }}</image-type>
          </template>
        </el-table-column>
        <el-table-column
          align="left"
          prop="size"
          min-width="60"
        >
          <template slot-scope="{ row }">{{ row.size | formatFileSize }}</template>
        </el-table-column>
        <!-- <el-table-column align="left" prop="status" min-width="50"></el-table-column> -->
        <el-table-column width="60">
          <template slot-scope="scope">
            <el-button
              type="text"
              size="mini"
              @click="handDelFile(scope.$index, scope.row)"
            >删除</el-button>
          </template>
        </el-table-column>
      </el-table>
      <!-- <span class="text">文件上传进度</span> -->
      <!-- <el-progress :percentage="uploadPress" :stroke-width="10" class="process"></el-progress> -->
    </div>
    <div
      class="footer"
      v-if="fileList.length"
    >
      <el-row type="flex">
        <span class="total">共{{ fileList.length }}个文件，总文件大小:{{ totalSize | formatFileSize}}</span>

        <el-progress
          v-if="uploadStatus === 'uploading'"
          style="width:30vh;"
          :percentage="uploadPress"
          :status="uploadProgressStatus"
          :stroke-width="10"
          :color="customColorMethod"
          class="process"
        ></el-progress>
        <span
          v-if="uploadStatus"
          class="result"
          :class="{error : uploadStatus === 'error'}"
        >{{ statusMapping[uploadStatus] }}</span>
      </el-row>
      <el-row
        type="flex"
        justify="center"
        class="toolBox"
      >
        <el-button
          type="primary"
          size="small"
          :disabled="uploading"
          @click="handUpload"
        >开始上传</el-button>
        <el-button
          type="default"
          size="small"
          @click="cancelUpload"
        >取消上传</el-button>
      </el-row>
    </div>
  </div>
</template>
<script>
import axios from "axios";
import Cookies from "js-cookie";
import { getFileType } from "@/utils/index.js";
export default {
  name: "FileUpload",
  props: {
    params: {
      type: Object,
      required: true
    },
    postUrl: {
      type: String,
      required: true
    },
    uploadFieldName: {
      type: String,
      default: "file"
    },
    multiple: {
      type: Boolean,
      default: true
    }
  },
  computed: {
    uploadProgressStatus() {
      return this.uploadPress === 100 ? "success" : "";
    }
  },
  components: {
    ImageType: () => import("@/components/ImageType")
  },
  data() {
    return {
      fileList: [], // 文件列表
      uploadPress: 0, // 上传进度
      uploadStatus: null,
      uploading: false,
      statusMapping: {
        uploading: "上传中...",
        compact: "处理中...",
        done: "上传完成",
        error: "上传失败",
        cancel: "已取消上传"
      },
      source: null // 取消上传
    };
  },
  methods: {
    // 选择文件
    handleChange(file, fileList) {
      const list = [];
      this.totalSize = fileList.reduce((p, v) => {
        return p + v.size;
      }, 0);
      fileList.forEach(e => {
        let type = { fileType: getFileType(e.name, ".") };
        list.push(Object.assign(e, type));
      });
      this.fileList = list;
      this.uploadStatus = null
    },
    // 删除文件
    handDelFile(index, row) {
      this.fileList.splice(index, 1);
      this.totalSize = this.fileList.reduce((p, v) => {
        return p + v.size;
      }, 0);
    },
    // 上传文件
    handUpload() {
      const that = this;
      that.uploading = true
      const form = new FormData();
      // 遍历上传参数
      let isNull = false;
      Object.keys(this.params).forEach(key => {
        // 参数判断 不为空
        if (!this.params[key]) {
          isNull = true;
        }
        form.append(key, this.params[key]);
      });
      if (isNull) {
        this.$message.warning("请输入文件上传参数");
        return;
      }
      this.uploadStatus = "uploading";
      this.uploadPress = 0;
      let cancelToken = axios.CancelToken;
      this.source = cancelToken.source();
      const config = {
        headers: {
          "Content-Type": "multipart/form-data",
          "X-CSRFToken": Cookies.get("csrftoken")
        },
        onUploadProgress: progressEvent => {
          let complete =
            ((progressEvent.loaded / progressEvent.total) * 100) | 0;
          this.uploadPress = Number(complete);
          if (this.uploadPress === 100) {
            this.uploadStatus = "compact";
          }
        },
        cancelToken: this.source.token //取消事件
      };
      if (this.fileList.length > 0) {
        this.fileList.forEach(e => {
          form.append(this.uploadFieldName, e.raw);
        });
      }
      axios
        .post(this.postUrl, form, config)
        .then(res => {
          if (res) {
            this.uploadStatus = "done";
            this.uploading = false
            this.$message({
              message: "文件上传成功",
              type: "success"
            });
            this.$emit("uploadFile");
          }
        })
        .catch(function(error) {
          that.$message.info("已取消上传文件");
          if (axios.isCancel(error)) {
            //主要是这里
            console.log("success", "成功", "取消上传镜像操作成功");
            that.uploadStatus = "cancel";
            that.uploading = false
            return;
          }
          that.uploadStatus = "error";
        });
    },
    cancelUpload() {
      if (this.source) {
        // 判断soucre是否存在
        this.source.cancel("取消上传");
        this.uploadPress = 0;
      }
      this.$emit("uploadFile");
    },
    // 进度条颜色区间
    customColorMethod(percentage) {
      if (percentage < 30) {
        return "#909399";
      } else if (percentage < 70) {
        return "#e6a23c";
      } else {
        return "#67c23a";
      }
    },
    clear() {
      this.fileList = [];
      this.uploadPress = 0;
      this.uploadResult = false;
      this.source = null;
    }
  }
};
</script>
<style lang="scss">
.file-upper {
  .footer {
    margin-top: 10px;
    .result {
      font-size: 14px;
      color: #4caf50;
      display: inline-block;
      margin-left: 10px;
    }
    .error {
      color: red;
    }
    .process {
      margin-left: 20px;
    }
    .toolBox {
      margin-top: 15px;
    }
  }
  .el-upload {
    width: 100%;
    // max-width: 50vh;
  }
  .el-upload-dragger {
    width: auto;
  }
  .el-upload-list {
    display: none;
  }
}
</style>